package com.blyat.xsoft.kernel.component.security;

import com.blyat.xsoft.kernel.component.security.exception.SecureException;
import com.blyat.xsoft.kernel.component.security.exception.code.SecurityErrorResult;
import com.blyat.xsoft.kernel.restful.view.ResultModel;
import com.blyat.xsoft.kernel.util.ServletUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author syh
 * @date 2019/8/21
 **/
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {

    private WebResponseExceptionTranslator<?> exceptionTranslator = new DefaultWebResponseExceptionTranslator();

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        try {
            ResponseEntity<?> result = exceptionTranslator.translate(accessDeniedException);
            if (result.getStatusCode() == HttpStatus.UNAUTHORIZED) {
                // refreshToken(request);
            } else {
                if (ServletUtil.isAjaxRequest()) {
                    ServletUtil.writer(ResultModel.FAIL(new SecureException(SecurityErrorResult.ACCESS_DENIED)));
                } else if (!response.isCommitted()) {
                    String errorPage = null;//PropertyPlaceHolder.getOrDefault("error.page", "/error").toString();
                    if (errorPage != null) {
                        request.setAttribute(WebAttributes.ACCESS_DENIED_403, accessDeniedException);
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);

                        RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage);
                        dispatcher.forward(request, response);
                    } else {
                        response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
